#!/bin/bash
#
# Copyright 2015-2017 Adrian DC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

# === .bashrc Update ===
function bashup()
{
  # Usage: bashup (Reload ~/.bashrc)

  # Reload ~/.bashrc
  source ~/.bashrc;
}

# === .bashrc Edit ===
function bashe()
{
  # Usage: bashe (Edit ~/.bashrc)

  # Edit ~/.bashrc
  fen ~/.bashrc;
}

# === Clear Screen ===
function cls()
{
  # Usage: cls (Clean terminal screen)

  # Clean terminal screen
  echo -e \\033c;
  clear;
}

# === Clipboard ===
function toclip() { xclip -selection c; }

# === Find Name ===
alias findn='find -name';

# === Folders Syncer ===
function rsynca()
{
  # Usage
  if [ -z "${2}" ]; then
    echo '';
    echo ' Usage: rsynca <path1> <path2> (Mirror a path to another)';
    echo '';
    return;
  fi;

  # Sync execution
  rsync -av --delete "${1}" "${2}";
}

# === Folders Fast Syncer ===
function rsyncf()
{
  # Usage
  if [ -z "${2}" ]; then
    echo '';
    echo ' Usage: rsyncf <path1> <path2> (Mirror a path to another based on size only)';
    echo '';
    return;
  fi;

  # Sync execution
  rsync -av --delete --size-only "${1}" "${2}";
}

alias pcinfo='inxi -Fxz';

# === Newer Files Finder ===
function findnewer()
{
  # Usage
  if [ -z "${1}" ]; then
    echo '';
    echo ' Usage: findnewer <20160123> (Search files newer than a date)';
    echo '';
    return;
  fi;

  # Search for newer files
  touch -t "${1}0000.01" /tmp/filetimeref;
  find . -type f -newer /tmp/filetimeref -print;
  rm -f /tmp/filetimeref;
}

# === CPIO Extractor ===
function cpioext()
{
  # Usage
  if [ -z "${1}" ]; then
    echo '';
    echo ' Usage: cpioext <cpio_file_to_extract> (Extract cpio file)';
    echo '';
    return;
  fi;

  # Variables
  local cwd;
  local file;
  local name;
  local outdir;

  # Extract cpio file
  cwd=$(pwd);
  file=$(echo "${1}" | sed 's/file:\/\/\(.*\)/\1/');
  name=$(basename "${file}");
  outdir=$(mktemp -d);
  cp "${file}" "${outdir}/";
  cd "${outdir}";
  cpio -i -F "${name}";
  diropen "${outdir}/";
  cd "${cwd}";
}

# === Video Resizer ===
function videoresize()
{
  # Usage
  if [ -z "${1}" ]; then
    echo '';
    echo ' Usage: videoresize <video_file> (Resize video dimensions)';
    echo '';
    return;
  fi;

  # Show and run command
  local command="mencoder ${1} -vf scale=480 -vf rotate=2 -ovc lavc -oac pcm -lavcopts vcodec=mpeg4:autoaspect -o ${1}.small.mp4";
  echo '';
  echo "${command}";
  echo '';
  ${command};
  echo '';
}

# === Automount Disabler ===
function disableautomount()
{
  # Usage: disableautomount (Linux USB automount disabler)

  # Linux USB automount disabler
  gsettings set org.cinnamon.desktop.media-handling automount-open false
  gsettings set org.cinnamon.desktop.media-handling automount false
  gsettings set org.gnome.desktop.media-handling automount-open false;
  gsettings set org.gnome.desktop.media-handling automount false;
}

# === Diff Binaries ===
function diffbin()
{
  # Usage
  if [ -z "${2}" ]; then
    echo '';
    echo ' Usage: diffbin <binary_left> <binary_right> [first_n_lines] (Compare binary files)';
    echo '';
    return;
  fi;

  # Full view
  if [ -z "${3}" ]; then
    diff -sy <(xxd "${1}") <(xxd "${2}") | less | colordiff;

  # Partial view
  else
    diff -sy <(xxd "${1}") <(xxd "${2}") | less | colordiff | head -n "${3}";
  fi;
}

# === Network Speed ===
function netspeed()
{
  # Usage: netspeed (Display network speeds)

  # Display network speeds
  echo '';
  dev_eth=$(grep -c eth0 /proc/net/dev);
  dev_wlan=$(grep -c wlan0 /proc/net/dev);
  tput sc;

  while [ "${dev_eth}" -ne 0 ] || [ "${dev_wlan}" -ne 0 ]; do
    if [ "${dev_eth}" -ne 0 ]; then
      vals_eth=$(awk '{if(l1){print ($2-l1)/1024"kB/s",($10-l2)/1024"kB/s"} else{l1=$2; l2=$10;}}' \
               <(grep eth0 /proc/net/dev) \
               <(sleep 1; grep eth0 /proc/net/dev));
    else
      vals_eth=;
    fi;
    if [ "${dev_wlan}" -ne 0 ]; then
      vals_wlan=$(awk '{if(l1){print ($2-l1)/1024"kB/s",($10-l2)/1024"kB/s"} else{l1=$2; l2=$10;}}' \
                <(grep wlan0 /proc/net/dev) \
                <(sleep 1; grep wlan0 /proc/net/dev));
    else
      vals_wlan=;
    fi;

    if [ ! -z "${vals_eth}" ]; then
      tput rc;
      tput ed;
      tput el;
      if [ ! -z "${vals_eth}" ]; then
        echo -e " \e[1;33mEthernet:\e[0m";
        echo -e "   Download: $(echo "${vals_eth}" | awk '{ print $1 }')";
        echo -e "   Upload: $(echo "${vals_eth}" | awk '{ print $2 }')";
      fi;
      if [ ! -z "${vals_wlan}" ]; then
        echo -e " \e[1;33mWLAN:    \e[0m";
        echo -e "   Download: $(echo "${vals_wlan}" | awk '{ print $1 }')";
        echo -e "   Upload: $(echo "${vals_wlan}" | awk '{ print $2 }')";
      fi;
    fi;
    sleep 1;
  done;
}

# === Net Speed Test ===
function netspeedtest()
{
  # Usage: netspeedtest (Run SpeedTest client)

  # Run SpeedTest client
  curl -s  https://raw.githubusercontent.com/sivel/speedtest-cli/master/speedtest.py | python -;
}

# === Drive Speed Test ===
function drivespeedtest()
{
  # Usage
  if [ -z "${1}" ] || [ -e "${1}" ]; then
    echo '';
    echo ' Usage: drivespeedtest <test_file_path> (Run drive write speed test)';
    echo '';
    return;
  fi;

  # Variables
  local path=${1};
  local time_diff;
  local value;

  # Run drive write speed test
  echo '';
  sync;
  time_diff=$(date +%s%N);
  time sh -c "dd if=/dev/zero of=${path} bs=100k count=1k && sync";
  time_diff=$(($(date +%s%N) - time_diff));
  rm "${path}";
  echo '';

  # Calculate performance
  value=$((104857600 * 1000 / time_diff));
  echo -e " \e[1;33m[ Path transfer performance: ${value} MB/s ]\e[0m";
  echo '';
}

# === Trim Trees ===
function trimtrees()
{
  # Usage: trimtrees <paths> (Hardlink duplicated files with trimtrees from cpansearch.perl.org)

  # Hardlink duplicated files with trimtrees from cpansearch.perl.org
  perl <(curl -Ls http://cpansearch.perl.org/src/ANDK/Perl-Repository-APC-2.002/eg/trimtrees.pl) "${@}";
}

# === Build Locker ===
function buildlock()
{
  # Usage
  if [ -z "${1}" ]; then
    echo '';
    echo ' Usage: buildlock <command...> (Mutex-locked command execution)';
    echo '';
    return;
  fi;

  # Variables
  local file_lock=${ANDROID_DEVELOPMENT_SHELL_TOOLS_WORKSPACE:-${HOME}}/.tmp_runlock.tag;

  # Lock Detected
  if [ -f "${file_lock}" ]; then
    echo '';
    echo " buildlock: The file '${file_lock}' still exists, waiting...";
    echo '';
    while [ -f "${file_lock}" ]; do sleep 10; done;
  fi;

  # Run work
  echo 1 > "${file_lock}";
  "${@}";
  rm -f "${file_lock}";
}

# === File Scheme Sorter ===
function fileschemesorter()
{
  # Usage
  if [ -z "${2}" ]; then
    echo '';
    echo ' Usage: fileschemesorter <file_to_sort> <file_reference> (Sort file against scheme file)';
    echo '';
    return;
  fi;

  # Variables
  local file_to_sort=${1};
  local file_reference=${2};
  local file_temp_1;
  local file_temp_2;
  local file_temp_3;

  # Initialize variables
  file_temp_1=$(mktemp);
  file_temp_2=$(mktemp);
  file_temp_3=$(mktemp);

  # Reference browse
  touch "${file_temp_1}";
  while read -r line; do

    # Relevant lines
    if [ ! -z "${line}" ] && grep -q "${line}$" "${file_to_sort}"; then
      echo "${line}" >> "${file_temp_1}";
    fi;

  done < "${file_reference}";

  # Final comparison
  sort "${file_to_sort}" -o "${file_temp_2}";
  sort "${file_temp_1}" -o "${file_temp_3}";
  meld "${file_temp_2}" "${file_temp_3}";
  meld "${file_to_sort}" "${file_temp_1}";
  echo '';
  echo ' Press [ENTER] to continue...';
  echo '';
  read -r;
  rm "${file_to_sort}";
  mv "${file_temp_1}" "${file_to_sort}";

  # Cleanup
  rm -f "${file_temp_2}";
  rm -f "${file_temp_3}";
}

# === USB MTP Mounts ===
function mtpmountdisable()
{
  # Usage
  if [ -z "${1}" ]; then
    echo '';
    echo ' Usage: mtpmountdisable (Disable MTP automount)';
    echo '';
    return;
  fi;

  # Disable MTP automount
  gsettings set org.cinnamon.desktop.media-handling automount-open false;
  gsettings set org.cinnamon.desktop.media-handling automount false;
}

# === CleanRAM ===
function cleanram()
{
  # Usage: cleanram (RAM caches cleanup)

  # Run cleanram script
  "${ANDROID_DEVELOPMENT_SHELL_TOOLS_DIR}/extensions/linux/run_cleanram.sh";
}

# === CleanRAM after builds ===
function cleanrambuild()
{
  # Usage: cleanrambuild (RAM caches cleanup)

  # Run cleanram script
  "${ANDROID_DEVELOPMENT_SHELL_TOOLS_DIR}/extensions/linux/run_cleanrambuild.sh";
}

# === CleanRAM with Kills ===
function cleanramkill()
{
  # Usage: cleanramkill [bool_cleanram] (Complete RAM cleanup including "java")

  # Kill relevant RAM eating processes
  killall adb;
  killall java;
  killall mega-cmd;

  # Run cleanram script
  if [ ! -z "${1}" ]; then
    cleanram;
  fi;
}

# === Network Manager Restart ===
function networkrestart()
{
  # Usage: networkrestart (Restart network manager)

  # Restart network manager
  sudo service network-manager restart;
}

# === Pushbullet Folder Sizes ===
function pushbsizes()
{
  # Usage
  if [ -z "${1}" ]; then
    echo '';
    echo ' Usage: pushbsizes <paths> (Path sizes in PushBullet notification)';
    echo '';
    return;
  fi;

  # Variables
  local message;

  # Notify all input sizes
  echo '';
  echo " Studying sizes of inputs: ${*}";
  echo '';
  message=$(du -csh "${@}" | tee /dev/stderr | tr '\t' ' ');
  pushb "${message//$'\n'/\\\n}";
}

# === Done Notification Sender ===
alias isdone='notify-send "Process execution finished !"';

# === Resources Monitor  ===
alias topcpu='top -o %CPU';
alias topmem='top -o %MEM';
